﻿
namespace System.Collections.Generic
{
    /// <summary>
    /// IDictionary扩展
    /// </summary>
    public static class ExIDictionary
    {
        /// <summary>
        /// 通过key获取对象 或者用 invoke 创建一个新对象的并添加到字典中
        /// </summary>
        /// <typeparam name="TKey">key类型</typeparam>
        /// <typeparam name="TValue">value类型</typeparam>
        /// <param name="dict">指定字典【NotNull】</param>
        /// <param name="key">搜索key【NotNull】</param>
        /// <param name="invokeCreateValue">创建一个新的对象 委托【NotNull】</param>
        /// <returns>对象</returns>
        public static TValue GetOrAddValue<TKey, TValue>(
            this IDictionary<TKey, TValue> dict, TKey key, Func<TValue> invokeCreateValue)
        {
            TValue result;
            if (!dict.TryGetValue(key, out result))
            {
                result = invokeCreateValue.Invoke();
                dict.Add(key, result);
            }
            return result;
        }

        /// <summary>
        /// 通过key获取对象 或者用 invoke 创建一个新对象的并添加到字典中
        /// </summary>
        /// <typeparam name="TKey">key类型</typeparam>
        /// <typeparam name="TValue">value类型</typeparam>
        /// <param name="dict">【NotNull】指定字典</param>
        /// <param name="key">【NotNull】搜索key</param>
        /// <param name="invoke">创建一个新的对象 委托【NotNull】</param>
        /// <param name="objs">创建一个新对象 参数【数量与invoke输入参数对应】</param>
        /// <returns>对象</returns>
        public static TValue GetOrAddValue<TKey, TValue>(
            this IDictionary<TKey, TValue> dict, TKey key,
            Func<object[], TValue> invoke, params object[] objs)
        {
            TValue result;
            if (!dict.TryGetValue(key, out result))
            {
                result = invoke.Invoke(objs);
                dict.Add(key, result);
            }
            return result;
        }

        /// <summary>
        /// 从字典中获取对象 找不到则返回default
        /// </summary>
        /// <typeparam name="TKey">key类型</typeparam>
        /// <typeparam name="TValue">value类型</typeparam>
        /// <param name="dict">指定字典【NotNull】</param>
        /// <param name="key">搜索key【NotNull】</param>
        /// <returns>对象</returns>
        public static TValue GetOrDefault<TKey, TValue>(
            this IDictionary<TKey, TValue> dict, TKey key)
        {
            TValue result;
            if (dict.TryGetValue(key, out result))
            {
                return result;
            }
            else
            {
                return default(TValue);
            }
        }

        /// <summary>
        /// 从字典中获取对象 找不到则返回default
        /// </summary>
        /// <typeparam name="TKey">key类型</typeparam>
        /// <typeparam name="TValue">value类型</typeparam>
        /// <param name="dict">指定字典【NotNull】</param>
        /// <param name="key">搜索key【NotNull】</param>
        /// <param name="defaultValue">搜索不到时的默认值</param>
        /// <returns>对象</returns>
        public static TValue GetOrDefault<TKey, TValue>(
            this IDictionary<TKey, TValue> dict, TKey key, TValue defaultValue)
        {
            TValue result;
            if (dict.TryGetValue(key, out result))
            {
                return result;
            }
            else
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 添加对象 存在则忽略
        /// </summary>
        /// <typeparam name="TKey">key类型</typeparam>
        /// <typeparam name="TValue">value类型</typeparam>
        /// <param name="dict">指定字典【NotNull】</param>
        /// <param name="key">搜索key【NotNull】</param>
        /// <param name="value">要插入的值</param>
        /// <returns>是否插入了值</returns>
        public static bool AddIfNotExist<TKey, TValue>(
            this IDictionary<TKey, TValue> dict,
            TKey key, TValue value)
        {
            if (dict.ContainsKey(key))
            {
                return false;
            }
            else
            {
                dict.Add(key, value);
                return true;
            }
        }

        /// <summary>
        /// 添加对象 存在则替换
        /// </summary>
        /// <typeparam name="TKey">key类型</typeparam>
        /// <typeparam name="TValue">value类型</typeparam>
        /// <param name="dict">指定字典【NotNull】</param>
        /// <param name="key">搜索key【NotNull】</param>
        /// <param name="value">要插入的值</param>
        /// <returns>是否替换了值</returns>
        public static bool AddOrReplace<TKey, TValue>(
            this IDictionary<TKey, TValue> dict,
            TKey key, TValue value)
        {
            bool blnResult = dict.ContainsKey(key);
            dict[key] = value;
            return blnResult;
        }
    }
}
